added SSCLI 1.0
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / VBWin7Direct2D / ReadMe.html
blob27ba9a8ac0dbc71278d9abb472afab2cdbdd10ca
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
6 <title>Working with Direct2D</title>
7 <style type="text/css">
8 h1 {
9 color: #FF0000;
11 h2 {
12 color: #6699FF;
14 </style>
16 </head>
18 <body>
20 <h1>Working with Direct2D</h1>
21 <h2>Introduction</h2>
22 <p>Windows 7 and Windows 2008 R2 come with a lot of cool new features. One of
23 the most exciting new features is a new graphic API powered by DirectX. It
24 allows you to take advantage of graphic cards to render complex scenarios. It
25 includes 3 components:</p>
26 <ul>
27 <li>Direct2D: API for drawing vector graphics.</li>
28 <li>DirectWrite: API for text rendering.</li>
29 <li>WIC (Windows Imaging Component): API for bitmaps encoding and decoding.
30 This API has been around since Windows Vista.</li>
31 </ul>
32 <p>Direct2D and DirectWrite will be ported to Vista in the future. But in
33 the meanwhile, you need Windows 7 in order to experience the power brought by
34 the new graphic engine.</p>
35 <p>Among all the three components, Direct2D is the most important. You need to
36 use Direct2D to render text and bitmap. DirectWrite and WIC do not touch
37 rendering on themselves. Also, only WIC relies on COM runtime. Direct2D and
38 DirectWrite can work without COM runtime. This sample focuses on Direct2D. We
39 will demonstrate other components in the future.</p>
40 <p>The main target audiences of the new graphic API are native application
41 developers. This sample (written in managed code) is just for demonstrating
42 purpose. Most managed applications should still use WPF, because WPF provides
43 you with a nice application framework and a nice UI framework. WPF uses Dirct3D
44 9 as its underlying rendering engine, while Direct2D uses Direct3D 10. In most
45 cases, you will not notice too much performance difference between WPF and
46 managed Direct2D. You will gain performance when hardware rendering is not an
47 option (such as server side batch operation), because Direct2D has an optimized
48 software rendering engine, as well as a hardware rendering engine. You may also
49 need Direct2D when working with Direct3D interop scenarios, to take advantages
50 of advanced GPU pipelines such as geometry shader.</p>
51 <p>This sample provides an overview of the new vector graphic API. It renders a
52 simple scene with a star (or sun) and a planet (or earth). When you click the
53 planet, it will move around the star.</p>
54 <p><img src="Screenshot.png" /></p>
55 <p>The sample demostrates the
56 following features:</p>
57 <ul>
58 <li>Draw simple vector graphics (such as ellipse).</li>
59 <li>Draw complex paths.</li>
60 <li>Create a PowerShell script to translate XAML path data to VB Direct2D
61 code.</li>
62 <li>Create solid color and radial gradient brushes.</li>
63 <li>Simple render transform.</li>
64 <li>Perform hit test.</li>
65 <li>Control z-index.</li>
66 <li>Clip path.</li>
67 </ul>
68 <p>For more information, please refer to the
69 <a href="http://msdn.microsoft.com/en-us/library/dd370990(VS.85).aspx">MSDN documents</a> and the Windows SDK
70 samples.</p>
71 <h2>Prepare the project</h2>
72 <p>To work with Direct2D, you can either manually write a managed wrapper, or
73 take advantage of the
74 <a href="http://code.msdn.microsoft.com/WindowsAPICodePack/Release/ProjectReleases.aspx?ReleaseId=3077">
75 Windows API Code Pack</a> (recommended). The Windows API Code Pack exposes most
76 (while not all) of the new Windows 7 and Direct 3D 10/11 features to managed
77 code. It should be sufficient in most scenarios.</p>
78 <p>Note since the DirectX part in the code pack is written in managed C++,
79 targeting x86, your managed application will have to target x86 as well (rather
80 than Any CPU) if you&#39;re running on a 64 bit OS. Alternatively, you can recompile
81 the code pack targeting x64. This is required if you want to use the code pack
82 in a 64 bit only environment, such as Windows Azure. This sample will target x86
83 only.</p>
84 <p>If you encounter a limitation, you can easily expose the missing feature by
85 modifying the source code. For example, the D3DX10CreateEffectFromFile function
86 in Direct3D, which allows you to load an HLSL file dynimacally without compiling
87 it using the fxc command line tool (and thus very useful during debugging), is
88 missing from the managed code pack. To expose it, you can modify the
89 D3D10Device.h file under DirectX/Header Files/D3D10/Core. In the D3DDevice
90 class, add a new method:</p>
91 <p align="left" class="MsoNormal">
92 <span lang="EN-US" style="font-size:9.0pt;font-family:
93 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
94 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
95 </span>Effect^ CreateEffectFromFile(String^ path);<o:p></o:p></span></p>
96 <p>Then find the corresponding source file, and implement this method:</p>
97 <p align="left" class="MsoNormal">
98 <span lang="EN-US" style="font-size:9.0pt;font-family:
99 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
100 mso-font-kerning:0pt;mso-no-proof:yes">Effect^ D3DDevice::CreateEffectFromFile(
101 String^ path)<o:p></o:p></span></p>
102 <p align="left" class="MsoNormal">
103 <span lang="EN-US" style="font-size:9.0pt;font-family:
104 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
105 mso-font-kerning:0pt;mso-no-proof:yes">{<o:p></o:p></span></p>
106 <p align="left" class="MsoNormal">
107 <span lang="EN-US" style="font-size:9.0pt;font-family:
108 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
109 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
110 </span>ID3D10Effect* pEffect = NULL;<o:p></o:p></span></p>
111 <p align="left" class="MsoNormal">
112 <span lang="EN-US" style="font-size:9.0pt;font-family:
113 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
114 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:1">&nbsp;&nbsp;&nbsp;&nbsp;
115 </span>IntPtr ptr = Marshal::StringToHGlobalUni(path);<o:p></o:p></span></p>
116 <p align="left" class="MsoNormal">
117 <span lang="EN-US" style="font-size:9.0pt;font-family:
118 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
119 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
120 </span>CommonUtils::VerifyResult(<o:p></o:p></span></p>
121 <p align="left" class="MsoNormal">
122 <span lang="EN-US" style="font-size:9.0pt;font-family:
123 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
124 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
125 </span>D3DX10CreateEffectFromFile( <o:p></o:p></span></p>
126 <p align="left" class="MsoNormal">
127 <span lang="EN-US" style="font-size:9.0pt;font-family:
128 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
129 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
130 </span>(LPCTSTR)ptr.ToPointer(),<o:p></o:p></span></p>
131 <p align="left" class="MsoNormal">
132 <span lang="EN-US" style="font-size:9.0pt;font-family:
133 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
134 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
135 </span>NULL,<o:p></o:p></span></p>
136 <p align="left" class="MsoNormal">
137 <span lang="EN-US" style="font-size:9.0pt;font-family:
138 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
139 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
140 </span>NULL,<o:p></o:p></span></p>
141 <p align="left" class="MsoNormal">
142 <span lang="EN-US" style="font-size:9.0pt;font-family:
143 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
144 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
145 </span><span style="color:#A31515">&quot;fx_4_0&quot;</span>,<o:p></o:p></span></p>
146 <p align="left" class="MsoNormal">
147 <span lang="EN-US" style="font-size:9.0pt;font-family:
148 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
149 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
150 </span>D3D10_SHADER_ENABLE_STRICTNESS,<o:p></o:p></span></p>
151 <p align="left" class="MsoNormal">
152 <span lang="EN-US" style="font-size:9.0pt;font-family:
153 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
154 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
155 </span>0,<o:p></o:p></span></p>
156 <p align="left" class="MsoNormal">
157 <span lang="EN-US" style="font-size:9.0pt;font-family:
158 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
159 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
160 </span><span style="color:blue">this</span>-&gt;GetInterface&lt;ID3D10Device&gt;(),<o:p></o:p></span></p>
161 <p align="left" class="MsoNormal">
162 <span lang="EN-US" style="font-size:9.0pt;font-family:
163 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
164 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
165 </span>NULL,<o:p></o:p></span></p>
166 <p align="left" class="MsoNormal">
167 <span lang="EN-US" style="font-size:9.0pt;font-family:
168 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
169 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
170 </span>NULL,<o:p></o:p></span></p>
171 <p align="left" class="MsoNormal">
172 <span lang="EN-US" style="font-size:9.0pt;font-family:
173 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
174 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
175 </span>&amp;pEffect,<o:p></o:p></span></p>
176 <p align="left" class="MsoNormal">
177 <span lang="EN-US" style="font-size:9.0pt;font-family:
178 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
179 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
180 </span>NULL,<o:p></o:p></span></p>
181 <p align="left" class="MsoNormal">
182 <span lang="EN-US" style="font-size:9.0pt;font-family:
183 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
184 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-tab-count:3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
185 </span>NULL));<o:p></o:p></span></p>
186 <p align="left" class="MsoNormal">
187 <span lang="EN-US" style="font-size:9.0pt;font-family:
188 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
189 mso-font-kerning:0pt;mso-no-proof:yes"><o:p>&nbsp;</o:p></span></p>
190 <p align="left" class="MsoNormal">
191 <span lang="EN-US" style="font-size:9.0pt;font-family:
192 新宋体;mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
193 mso-font-kerning:0pt;mso-no-proof:yes"><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;
194 </span><span style="color:blue">return</span> pEffect ?
195 <span style="color:
196 blue">gcnew</span> Effect( pEffect ) : <span style="color:blue">nullptr</span>;<o:p></o:p></span></p>
197 <p class="MsoNormal">
198 <span lang="EN-US" style="font-size:9.0pt;font-family:新宋体;
199 mso-hansi-font-family:&quot;Times New Roman&quot;;mso-bidi-font-family:&quot;Times New Roman&quot;;
200 mso-font-kerning:0pt;mso-no-proof:yes">}</span></p>
201 <p>The wrapper for the new Graphic API is written in managed C++, so you also
202 need to use managed C++ to expose more features. On the other hand, if you&#39;re
203 working with other new features of Windows 7, such as the new task bar, and you need
204 to expose additional features of the underlying platform, you can simply use VB/C#.</p>
205 <p>All features used in this sample are already exposed via the code pack.</p>
206 <h2>Essential steps to work with Direct2D</h2>
207 <p>To work with Direct 2D, the following steps are required:</p>
208 <ul>
209 <li>Create a factory.</li>
210 <li>Create a render target. The render target represents the actual divide.
211 It can be a simple hwnd (as demonstrate in this sample), a Direct3D device
212 (DXGI), or anything else.</li>
213 <li>Create other resources, such as brushes.</li>
214 <li>Handle the WM_PAINT message, and render the scene. In managed code, you
215 perform this step by writing a method that implements the Render delegate of
216 the Render/DirectHost.</li>
217 </ul>
218 <p>To render the scene, the following steps are required:</p>
219 <ul>
220 <li>Call BeginDraw to initializing the scene.</li>
221 <li>Set the transform matrix for the next graph.</li>
222 <li>Prepare the graph, if necessary. For example, create a bounding
223 rectangle for text.</li>
224 <li>Call various drawing functions to draw vector/bitmap graphics and texts.</li>
225 <li>Call EndDraw to flush the drawing instructions.</li>
226 </ul>
227 <p>A note about gradient brushes. Unlike WPF, in Direct2D, gradient brushes
228 always use global coordinate system. So you have to do additional work to
229 calculate the position of each gradient stop.</p>
230 <h2>Draw complex paths</h2>
231 <p>It is almost impossible to draw complex paths without first creating them in
232 a graphic authoring tool. WPF allows you to draw paths in Expression Design (or
233 Expression Blend directly if the path is not too complex), and then export to
234 XAML. WPF can directly render XAML content as vector graphics. With Direct2D,
235 you do not have the luxuriate to utilize XAML. Traditionally, programmers tend
236 to use bitmaps extensively, and avoid vector graphics as much as possible.
237 However, bitmaps have a lot of disadvantages, such as difficult to animate and
238 losing quality during scaling. Nowadays with WPF, a lot of managed applications
239 have begun to use more and more vector graphics. Our native applications must
240 catch up with them. Also Direct2D is a vector graphic API. So it will be great
241 if we can use Expression Studio, but output Direct2D code instead of XAML.</p>
242 <p>You can try to create a tool to perform the translation. This sample provides
243 you with a general idea. XAML is xml, and there&#39;s a powerful tool in Windows 7
244 (and can be downloaded separately in Vista) named PowerShell. PowerShell is
245 capable of a lot of tasks, including parsing xml files. You can use the WPF
246 powered GUI PowerShell ISE to authorize PowerShell scripts. Assume your path
247 contains bezier segments only, you can use the following script to generate VB
248 code from XAML snip.</p>
249 <p>$invocation = (Get-Variable MyInvocation -Scope 0).Value $currentDir = Split-Path
250 $invocation.InvocationName cd $currentDir $xmlData = [xml](Get-Content $args[0])
251 $segments = $xmlData.PathFigure.SelectNodes(&quot;BezierSegment&quot;) $segments |
252 ForEach-Object { &quot;sink.AddBezier(New BezierSegment(New Point2F({0}!, {1}!), New
253 Point2F({2}!, {3}!), New Point2F({4}!, {5}!)))&quot; -f
254 $_.GetAttribute(&quot;Point1&quot;).split(&#39;,&#39;)[0],
255 $_.GetAttribute(&quot;Point1&quot;).split(&#39;,&#39;)[1],
256 $_.GetAttribute(&quot;Point2&quot;).split(&#39;,&#39;)[0],
257 $_.GetAttribute(&quot;Point2&quot;).split(&#39;,&#39;)[1],
258 $_.GetAttribute(&quot;Point3&quot;).split(&#39;,&#39;)[0], $_.GetAttribute(&quot;Point3&quot;).split(&#39;,&#39;)[1]
259 } &gt; $args[1]</p>
260 <p>For more information about PowerShell, please refer to
261 <a href="http://www.microsoft.com/technet/scriptcenter/topics/winpsh/manual/default.mspx">
262 http://www.microsoft.com/technet/scriptcenter/topics/winpsh/manual/default.mspx</a>.</p>
263 <h2>Render transforms</h2>
264 <p>Unlike WPF, in Direct2D, there&#39;s no object tree. A
265 transform is applied to the whole render target, which affects all pending
266 drawing instructions, not to a particular object. So after you want to transform
267 the planet using matrix a, and then want to transform the star with matrix b,
268 you need to follow these steps:</p>
269 <ul>
270 <li>Call SetTransform, passing matrix a as the parameter.</li>
271 <li>Draw all elements containing in the planet. They will all use matrix a.</li>
272 <li>Call SetTransform, passing matrix b as the parameter.</li>
273 <li>Draw all elements containing in the star. They will all use matrix b.</li>
274 </ul>
275 <p>If you want to draw an untransformed element, please set the transform back
276 to an identity matrix before drawing it.</p>
277 <p>Note currently the managed code pack does not support Direct2D matrix
278 multiplication. As a workaround, you can either implement your own, or simply
279 create WPF matrixes to perform the multiplications.</p>
280 <h2>Hit test</h2>
281 <p>To handle mouse input, you handle the standard Win32 message loop.
282 Input system is independent from rendering engines such as Direct2D. However,
283 there is a limitation in WPF and Direct2D interop scenario. You can&#39;t handle the
284 mouse/keyboard events by specifying the event handlers in XAML, because a
285 seperate hwnd is created to render the Direct2D content. You have to handle
286 ComponentDispatcher.ThreadPreprocessMessage to get the Win32 message loop, as
287 you do in a normal WPF/Win32 interop scenario.</p>
288 <p>To perform hit test, you call the FillContainsPoint function on the geometry
289 (or StrokeContainsPoint if you only want to hit test the stroke). Note when
290 drawing known geometries (such as ellipse), normally you do not need to create a
291 geometry. However, if you want to perform hit test on the known gemetry, you
292 have to explicitly create it.</p>
293 <p>Unlike WPF, with Direct2D&#39;s immediate rendering model, it does not retain a
294 tree about each geometry&#39;s transform, so you must explicitly pass the transform
295 matrix as a parameter in FillContainsPoint.</p>
296 <h2>Z-index</h2>
297 <p>Once again, in an immediate rendering envionment, you lose the track of
298 previous rendered elements. It will be impossible to say, hey, the planet is
299 rendered later than the star, but I hope the star will cover the planet. There&#39;s
300 no concept of z-index in Direct2D. To simulate z-index, you will have to plan
301 carefully on the order of the elements being rendered. For exmaple, if you hope
302 the star to cover the planet, draw the planet first and then the star. On the
303 othe hand, if you hope the planet to cover the star, draw the star first and
304 then the planet.</p>
305 <h2>Clip path</h2>
306 <p>Direct2D doesn&#39;t support clipping path directly. However, a similar effect
307 can be achieved by intersecting the geometry with the clipping path. To perform
308 common geometry operations (such as intersect and union), you need to prepare
309 the two source geometries first, and then call CombineWithGeometry on the first
310 geometry, passing the second geometry as the parameter, and finally save the
311 result to a third geometry. Please remember to delete the source geometries if
312 you no longer need them.</p>
313 <h2>Conclusion</h2>
314 <p>Windows 7 ships with a new vector graphic API: Direct2D. It primarily targets
315 native developers, but you can also use it in managed applications, if you want.
316 However, for most managed applications, you should still use WPF. You can embed
317 Direct2D scenes inside a WPF application.</p>
319 </body>
321 </html>